#ifndef __UDS_FP_H
#define __UDS_FP_H
#ifdef _cplusplus
extern "C" {
#endif
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <time.h>

#include "list.h"
#include "cJSON_ext.h"
#include "cJSON.h"

#ifndef UDS_FP_MALLOC
#define UDS_FP_MALLOC	malloc
#endif

#ifndef UDS_FP_FREE
#define UDS_FP_FREE		free
#endif

#define MTU_MAX     (1024 * 200)
#define FRAME_HEAD  0xA5
typedef enum
{
    RES_TIMEOUT = -1,
    RES_SUCCESS = 0,
}res_type_e;

typedef enum
{
    FRAME_TYPE_NOTIFY = 0,  //通知 
    FRAME_TYPE_ACK ,        //应答

}frame_type_e;


/*
    回调函数类型定义( cSJON传参皆有外部释放！！！)
    参数说明：res 帧解析结果
            cJSON *mess_in: uds接收到的请求或者请求应答
            cJSON *messout：需要发出的应答（如果本身就是接收应答则为NULL）
            
*/
typedef int (*listen_callback_func)(res_type_e res, cJSON *mess_in, cJSON *mess_ack);   
typedef int (*tx_callback_func)(res_type_e res, cJSON *mess_in);   

typedef struct {

    uint8_t         head;
    frame_type_e    frame_type;
    uint8_t         check_sum;
    uint32_t        payload_len;
    uint8_t         payload[];
} __attribute__ ((packed)) t_frame;

typedef struct _t_uds_fp_tx {
    uint32_t outtime_sec;            //发送帧超时时间
    struct timespec occurred_time;             //发送帧发生时间，用于rx事件中判断超时 sec

    t_frame *pframe;                //帧信息
    tx_callback_func tx_cb_func;          
    struct list_head list;
} t_uds_fp_tx,*pt_uds_fp_tx;


typedef struct _t_uds_fp_listen {
    char *topic;                        //监听字段内容
    char *from_sock_path;               //如果不为空，则指定了消息来源
    listen_callback_func listen_cb_func;          
    struct list_head list;
} t_uds_fp_listen,*pt_uds_fp_listen;

int tx_data_ack_timeout_handle(struct list_head *plist_tx);
void rx_data_decode_handle(uint8_t *pbuff,int64_t len,struct list_head *tx_list,struct list_head *listen_list);
pt_uds_fp_tx tx_msg_create_handle(  pt_uds_fp_tx plist_tx,\
                                    char *pdata,\
                                    int64_t len,\
                                    uint32_t outtime_sec,\
                                    tx_callback_func cb_func);
void tx_msg_free_handle(pt_uds_fp_tx tmp);

t_frame *ack_msg_create_handle(char *pdata,int64_t len);
void ack_msg_free_handle(t_frame *tmp);

pt_uds_fp_listen listen_msg_create_handle(pt_uds_fp_listen plist_listen,\
                                     char *topic,\
									 char *from,\
                                    listen_callback_func cb_func);
int listen_msg_free_handle(pt_uds_fp_listen plist_listen, char *topic, char *src);


#ifdef _cplusplus
}
#endif
#endif
